package com.lv.common.base

import android.app.Activity
import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.CallSuper
import androidx.annotation.ColorRes
import androidx.annotation.LayoutRes
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.ConvertUtils
import com.lv.common.R
import com.lv.common.lce.DefaultLceImpl
import com.lv.common.lce.ILce
import com.lv.common.utils.StatusBarUtil
import com.lv.common.utils.showToast
import me.jessyan.autosize.internal.CustomAdapt

/**
 * 作者： ygx
 * 创建日期：2022/1/20 9:21 PM
 * 签名： 天行健，君子以自强不息；地势坤，君子以厚德载物。
 *      _              _           _     _   ____  _             _ _
 *     / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 *    / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 *   / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 *  /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 *
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 * Fragment的抽象基类
 */
abstract class BaseFragment : Fragment, ILce, CustomAdapt {

    /**
     * 无参构造函数
     */
    constructor() : super()


    /**
     * Fragment中由于服务器异常导致加载失败显示的布局。
     */
    private var loadErrorView: RelativeLayout? = null

    /**
     * Fragment中由于网络异常导致加载失败显示的布局。
     */
    private var badNetworkView: RelativeLayout? = null

    /**
     * Fragment中当界面上没有任何内容时展示的布局。
     */
    private var noContentView: RelativeLayout? = null


    /**
     * Fragment中显示加载等待的控件。
     */
    private var loading: RelativeLayout? = null

    private var defaultLce: ILce? = null

    /**
     * 是否有顶部间距
     */
    protected open fun isHaveHeadMargin(): Boolean {
        return false
    }

    /**
     * 可以填入layout布局的构造函数，使用viewBinding的方便
     * [layout] layout布局文件的id
     */
    constructor(@LayoutRes layout: Int) : super(layout)

    //UI的viewDataBinding对象
    private var mBinding: ViewDataBinding? = null


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val frameLayout = FrameLayout(requireContext())
        val lce = View.inflate(context, R.layout.layout_lce, null)
        val params = FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT
        )
        val isPort = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
        params.setMargins(
            0,
            if (isHaveHeadMargin()) {
                ConvertUtils.dp2px(if (isPort) 70f else 55f)
            } else 0,
            0,
            0
        )
        val inflate = inflater.inflate(getLayoutRes(), container, false)
        lce.layoutParams = params
        frameLayout.addView(inflate)
        frameLayout.addView(lce)
        onCreateViews(lce, inflate, savedInstanceState)
        return frameLayout
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        initConfig()
        initData()
        initEvents()
    }

    @LayoutRes
    abstract fun getLayoutRes(): Int

    abstract fun bindView(view: View, savedInstanceState: Bundle?): ViewDataBinding

    /**
     * view初始化后的必要配置
     */
    open fun initConfig() {
//        LogUtils.d("${this.javaClass.simpleName} 初始化 initConfig")
    }

    open fun initStatusBar(
        mContext: Activity,
        isImmersive: Boolean,
        isBlackFont: Boolean,
        @ColorRes toolbarColor: Int = R.color.colorWhite,
        alpha: Float = 1.0f
    ) {
        //沉浸式实现
        if (isImmersive) {
            StatusBarUtil.immersive(mContext)
        } else {
            //状态栏颜色  activity  color(状态栏颜色值) alpha（透明度，取值范围 0.0f - 1.0f ）
            StatusBarUtil.darkMode(mContext, resources.getColor(toolbarColor), alpha)
        }

        //填充View id：控件id
//        StatusBarUtil.setPaddingSmart(this, id)

        //状态栏字体颜色  true：黑色  false：白色
        StatusBarUtil.darkMode(mContext, isBlackFont)


    }

    /**
     * view初始化后的必要数据
     */
    open fun initData() {
//        LogUtils.d("${this.javaClass.simpleName} 初始化 initData")
    }

    /**
     * view初始化后的事件处理
     */
    open fun initEvents() {
//        LogUtils.d("${this.javaClass.simpleName} 初始化 initConfig")
    }

    override fun onDestroy() {
        super.onDestroy()
        mBinding?.unbind()
    }


    /**
     * 扩展用于liveData便捷写法的函数
     * [block]liveData对象，响应change变化的逻辑块
     */
    protected fun <T : Any> LiveData<T>.observeKt(block: (T?) -> Unit) {
        this.observe(viewLifecycleOwner, Observer {
            block(it)
        })
    }

    override fun isBaseOnWidth(): Boolean {
        return true
    }

    override fun getSizeInDp(): Float {
        return 360.0f
    }

    /**
     * 设置 LiveData 的状态，根据不同状态显示不同页面
     *
     * @param dataLiveData LiveData
     * @param onDataStatus 数据回调进行使用
     */
    fun <T> setDataStatus(
        dataLiveData: LiveData<Result<T>>,
        onBadNetwork: () -> Unit = {},
        onDataStatus: (T) -> Unit
    ) {
        dataLiveData.observe(this) {
            if (it.isSuccess) {
                val dataList = it.getOrNull()
                if (dataList != null) {
                    loadFinished()
                    onDataStatus(dataList)
                } else {
                    showLoadErrorView()
                }
            } else {
                showToast(getString(R.string.bad_network_view_tip))
                showBadNetworkView { initData() }
                onBadNetwork.invoke()
            }
        }
    }

    /**
     * 在Fragment基类中获取通用的控件，会将传入的View实例原封不动返回。
     * @param view
     * Fragment中inflate出来的View实例。
     * @return  Fragment中inflate出来的View实例原封不动返回。
     */
    private fun onCreateViews(view: View, inflater: View, savedInstanceState: Bundle?): View {
        loading = view.findViewById(R.id.loading)
        noContentView = view.findViewById(R.id.noContentView)
        badNetworkView = view.findViewById(R.id.badNetworkView)
        loadErrorView = view.findViewById(R.id.loadErrorView)

        if (loading == null) {
            throw NullPointerException("loading is null")
        }
        if (badNetworkView == null) {
            throw NullPointerException("badNetworkView is null")
        }
        if (loadErrorView == null) {
            throw NullPointerException("loadErrorView is null")
        }
        defaultLce = DefaultLceImpl(
            loading,
            loadErrorView,
            badNetworkView,
            noContentView
        )
        mBinding = bindView(inflater, savedInstanceState)
        mBinding?.lifecycleOwner = viewLifecycleOwner
        return view
    }

    @CallSuper
    override fun startLoading(tip: String, boolean: Boolean) {
        defaultLce?.startLoading(tip, boolean)
    }

    @CallSuper
    override fun loadFinished() {
        defaultLce?.loadFinished()
    }


    override fun showLoadErrorView(
        tip: String, resouse: Int,
        showBack: Boolean,
        callback: View.OnClickListener?
    ) {
        defaultLce?.showLoadErrorView(tip, resouse, showBack, callback)
    }

    override fun showBadNetworkView(listener: View.OnClickListener) {
        defaultLce?.showBadNetworkView(listener)
    }

    override fun showNoContentView(tip: String) {
        defaultLce?.showNoContentView(tip)
    }

    open fun getEmptyView(
        rvContent: RecyclerView,
        tip: String = "暂无信息",
        empty: Int = R.drawable.icon_empty,
        isShowLogin: Boolean = false
    ): View {
        val view: View = layoutInflater.inflate(R.layout.empty_view, rvContent, false)
        val ivImg = view.findViewById<ImageView>(R.id.iv_img)
        val tvEmpty = view.findViewById<TextView>(R.id.tv_empty)
        ivImg.setImageResource(empty)
        tvEmpty.text = tip
        return view
    }

    fun getEmptyCenterView(
        rvContent: RecyclerView,
        tip: String = "暂无信息",
        empty: Int = R.drawable.icon_empty,
        isShowLogin: Boolean = false
    ): View {
        val view: View = layoutInflater.inflate(R.layout.empty_center_view, rvContent, false)
        val ivImg = view.findViewById<ImageView>(R.id.iv_img)
        val tvEmpty = view.findViewById<TextView>(R.id.tv_empty)
        ivImg.setImageResource(empty)
        tvEmpty.text = tip

        return view
    }
}